package com.learning.security.service;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.learning.security.dal.dataobject.RoleDO;
import com.learning.security.dal.dataobject.UserDO;
import com.learning.security.dal.mysql.UserMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsPasswordService;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Objects;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author xxx
 * @since 2024-09-18
 */
// @Service
public class UserServiceImpl extends ServiceImpl<UserMapper, UserDO> implements UserService, UserDetailsService, UserDetailsPasswordService {
    @Autowired
    private UserMapper userMapper;

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        LambdaQueryWrapper<UserDO> userQuery = new LambdaQueryWrapper<>();
        userQuery.eq(UserDO::getUsername, username);
        UserDO userDO = userMapper.selectOne(userQuery);
        if (Objects.isNull(userDO)) {
            throw new UsernameNotFoundException("用户不存在");
        }

        List<RoleDO> roles = userMapper.getRolesByUid(userDO.getId());
        userDO.setRoles(roles);
        return userDO;
    }

    @Override
    public UserDetails updatePassword(UserDetails user, String newPassword) {
        LambdaUpdateWrapper<UserDO> userUpdateWrapper = new LambdaUpdateWrapper<UserDO>();
        userUpdateWrapper.eq(UserDO::getUsername, user.getUsername())
                .set(UserDO::getPassword, newPassword);
        int result = userMapper.update(userUpdateWrapper);
        // 根据更新的受影响的行数判断是否进行了更新，为1时表示更新成功
        if (result == 1) {
            ((UserDO) user).setPassword(newPassword);// 更新内存中用户的密码
        }
        return user;
    }
}
